package com.vegetable.modules.service.outbound.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.common.constant.CommonConstant;
import com.vegetable.common.utils.Constant;
import com.vegetable.common.utils.PageUtils;
import com.vegetable.common.utils.Query;
import com.vegetable.common.utils.R;
import com.vegetable.modules.entity.baseData.AccountDetails;
import com.vegetable.modules.entity.baseData.AddressBook;
import com.vegetable.modules.entity.baseData.Products;
import com.vegetable.modules.entity.outbound.SalesOrderDetailStock;
import com.vegetable.modules.entity.outbound.SalesProxy;
import com.vegetable.modules.entity.outbound.SalesProxyDetail;
import com.vegetable.modules.entity.stock.Stock;
import com.vegetable.modules.mapper.outbound.SalesProxyMapper;
import com.vegetable.modules.service.baseData.IAccountDetailsService;
import com.vegetable.modules.service.baseData.IAddressBookService;
import com.vegetable.modules.service.baseData.IProductsService;
import com.vegetable.modules.service.outbound.ISalesOrderDetailStockService;
import com.vegetable.modules.service.outbound.ISalesProxyDetailService;
import com.vegetable.modules.service.outbound.ISalesProxyService;
import com.vegetable.modules.service.stock.IStockFlowService;
import com.vegetable.modules.service.stock.IStockService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 代销发货 服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-04-02
 */
@Slf4j
@Service
@AllArgsConstructor
public class SalesProxyServiceImpl extends ServiceImpl<SalesProxyMapper, SalesProxy> implements ISalesProxyService {

    private ISalesProxyDetailService detailService;
    // 销售商品明细库存对照表
    private ISalesOrderDetailStockService detailStockService;
    // 产地商品
    private IProductsService productsService;
    // 库存管理
    private IStockService stockService;
    // 通讯录
    private IAddressBookService addressBookService;
    // 往来明细
    private IAccountDetailsService accountDetailsService;
    // 库存流水
    private IStockFlowService iStockFlowService;

    /**
     * 代销发货列表查询
     * @param params
     * @return
     */
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        // 状态状态0在售，1售完
        Object state = params.get("state");
        String startTime = (String)params.get("startTime");
        String endTime = (String)params.get("endTime");
        // 单号
        String docNo = (String)params.get("docNo");
        IPage<SalesProxy> page = this.page(
                new Query<SalesProxy>().getPage(params),
                new QueryWrapper<SalesProxy>()
                        .between(StringUtils.isNotBlank(startTime), "order_time", startTime, endTime)
                        .eq(ObjectUtils.isNotEmpty(state),"state", state)
                        .eq(ObjectUtils.isNotEmpty(params.get("customerId")),"customer_id", params.get("customerId"))
                        .like(StringUtils.isNotBlank(docNo),"doc_no", docNo)
                        .orderByDesc("create_time")
        );

        return new PageUtils(page);
    }

    /**
     * 详情代销发货
     * @param id null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    public R detailSalesProxy(Long id) {
        SalesProxy salesProxy = baseMapper.selectById(id);
        if (salesProxy == null){
            return R.fail("订单不存在");
        }
        // 查询原订单的商品
        QueryWrapper<SalesProxyDetail> detailQuery = new QueryWrapper();
        detailQuery.eq("sales_id", salesProxy.getId());
        List<SalesProxyDetail> details = detailService.getBaseMapper().selectList(detailQuery);
        if (CollectionUtils.isNotEmpty(details)){
            for (SalesProxyDetail detail:details) {
                Products products = productsService.getById(detail.getCommodityId());
                detail.setCommodityCode(products.getCommonCode());
                List<SalesOrderDetailStock> detailStocks = detailStockService.getBaseMapper().selectList(
                        Wrappers.<SalesOrderDetailStock>query().lambda()
                                .eq(SalesOrderDetailStock::getDetailId, detail.getId()));
                detail.setStocks(detailStocks);
            }
            salesProxy.setCommodities(details);
        }
        return R.data(salesProxy);
    }

    /**
     * 新增代销发货
     * @param salesProxy null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R saveSalesProxy(SalesProxy salesProxy) throws Exception {
        // 新增入库采购收货主表
        if (CollectionUtils.isEmpty(salesProxy.getCommodities())){
            throw new Exception("商品列表不能为空");
        }
        // 商品总数
        Integer number = 0;
        // 商品总重
        BigDecimal weight = BigDecimal.ZERO;
        BigDecimal cost = BigDecimal.ZERO;
        for (SalesProxyDetail orderDetail: salesProxy.getCommodities()) {
            if (orderDetail.getNumber()==0){
                throw new Exception("商品数量不能为0");
            }
            number = number+orderDetail.getNumber();
            weight = weight.add(orderDetail.getWeight());
            if (orderDetail.getCost() != null){
                cost = cost.add(orderDetail.getCost());
            }
        }
        salesProxy.setNumber(number);
        salesProxy.setWeight(weight);
        salesProxy.setCost(cost);
        salesProxy.setOrderTime(new Date());
        if (salesProxy.getId() == null){
            salesProxy.setDocNo(CommonConstant.DXFH+ baseMapper.getNextCode());
            save(salesProxy);
        }else {
            // 修改主表数据
            updateById(salesProxy);
            // 删除其他费用，商品信息，已经商品下的信息
            deleteMethod(salesProxy);
        }
        // 入库采购收货主键
        Long mainId = salesProxy.getId();
        // 保存订单下明细
        saveDetailInfo(mainId, salesProxy);

        return R.data(mainId);
    }

    /**
     * 保存订单下明细
     * @param mainId
     * @param salesProxy
     * @return
     */
    private R saveDetailInfo(Long mainId, SalesProxy salesProxy){
        // 保存订单下明细
        log.info("保存订单下明细:{}", JSON.toJSONString(salesProxy.getDocNo()));
        List<SalesProxyDetail> commodities = salesProxy.getCommodities();
        for (SalesProxyDetail deliveryDetail: commodities) {
            deliveryDetail.setId(null);
            deliveryDetail.setSalesId(mainId);
            log.info("保存代销发货商品明细表");
            detailService.save(deliveryDetail);
            List<SalesOrderDetailStock> stocks = deliveryDetail.getStocks();
            if (CollectionUtils.isNotEmpty(stocks)){
                for (SalesOrderDetailStock detailStock:stocks) {
                    detailStock.setOrderId(mainId);
                    detailStock.setDetailId(deliveryDetail.getId());
                }
                log.info("保存代销发货商品对应库存明细表");
                detailStockService.saveBatch(stocks);
            }
        }
        return R.data(mainId);
    }

    /**
     * 提交代销发货
     * @param salesProxy null
     * @return R
     * @author wrj
     * @since 2024/3/7 下午4:35
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R submitSalesProxy(SalesProxy salesProxy) throws Exception {
        //状态0未出库，1已出库 2部分出库
        if (salesProxy.getState().intValue() == 1){
            throw new Exception("订单是已售完状态，不能操作");
        }
        salesProxy.setState(1);
        salesProxy.setMoney(salesProxy.getMoney());
        updateById(salesProxy);
        // 更新出库库存
        saveOutStock(salesProxy);
        // 更新客商金额
        updateArrears(salesProxy);
        // 更新客商往来明细
        saveAccountDetails(salesProxy);

        return R.status(true);
    }

    /**
     * 更新出库 库存
     * @param salesProxy null
     * @return void
     * @author wrj
     * @since 2024/3/22 上午11:49
     */
    private void saveOutStock(SalesProxy salesProxy) throws Exception {

        // 更新出库库存
        for (SalesProxyDetail detail :salesProxy.getCommodities()) {
            BigDecimal price_unit = detail.getCost().divide(detail.getWeight(), 2, RoundingMode.HALF_UP);
            if (CollectionUtils.isNotEmpty(detail.getStocks())){
                for (SalesOrderDetailStock detailStock :detail.getStocks()) {
                    Stock stock = stockService.getBaseMapper().selectById(detailStock.getStockId());
                    if (stock != null){
                        log.info("代销发货商品出库更新库存，原库存：{}", JSON.toJSONString(stock));
                        BigDecimal changeNum = NumberUtil.equals(stock.getStandard(), BigDecimal.ZERO) ? detail.getWeight() : new BigDecimal(detail.getNumber());
                        // 累加到第一条
                        stock.setNumber(stock.getNumber() - detail.getNumber());
                        BigDecimal weight = stock.getWeight();
                        weight = weight.subtract(detail.getWeight());
                        stock.setWeight(weight);
                        BigDecimal cost = stock.getCost();
                        cost = cost.add(price_unit.multiply(detail.getWeight()));
                        stock.setCost(cost);
                        // 成本/重量
                        BigDecimal costWeight = stock.getCost().divide(stock.getWeight(), 6, RoundingMode.HALF_UP);
                        stock.setCostWeight(costWeight);
                        log.info("代销发货商品出库更新库存，新库存：{}", JSON.toJSONString(stock));
                        if (stock.getNumber() > 0 && stock.getWeight().compareTo(BigDecimal.ZERO) == 0){
                            stockService.updateById(stock);
                        }else {
//                            stockService.removeById(stock);
                        }
                        iStockFlowService.addStockFlow(stock, Constant.StockFlowType.AGENT_SALE_OUT.getValue(),  changeNum, stock.getStorageOrderNo(), salesProxy.getCustomerName(), salesProxy.getOrderTime());
                    }else {
                        log.info("代销出库商品出库更新库存不存在:{}", detailStock.getStockId());
                        throw new Exception("代销发货库存id下的库存不存在："+detailStock.getStockId());
                    }
                }
            }
        }
    }

    /**
     * 更新待办,班组的应收金额
     *
     * @param salesProxy null
     * @return void
     * @author wrj
     * @since 2024/3/22 上午11:47
     */
    private void updateArrears(SalesProxy salesProxy){
        // 更新待办的应收金额
        AddressBook addressBook = addressBookService.getById(salesProxy.getCustomerId());
        BigDecimal arrears = addressBook.getArrears();
        // 加上该订单代办应收金额
        arrears = arrears.add(salesProxy.getMoney());
        addressBook.setArrears(arrears);
        addressBookService.updateById(addressBook);
    }


    /**
     * 新增客商的往来明细
     * @param salesProxy null
     * @return void
     * @author wrj
     * @since 2024/3/22 上午11:44
     */
    private void saveAccountDetails(SalesProxy salesProxy){
        // 生成代办的往来明细
        AccountDetails accountDetails = new AccountDetails();
        accountDetails.setStaffType(1); // 客商
        accountDetails.setPersonId(salesProxy.getCustomerId());
        accountDetails.setDetailType(8); // 代销
        accountDetails.setOrderId(salesProxy.getId());
        accountDetails.setOrderTime(salesProxy.getOrderTime());
        accountDetails.setDocNo(salesProxy.getDocNo());
        accountDetails.setMoney(salesProxy.getMoney());
        log.info("代销发货保存客商的的往来明细：{}", JSON.toJSONString(accountDetails));
        QueryWrapper<AccountDetails> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AccountDetails::getOrderId, salesProxy.getId());
        wrapper.lambda().eq(AccountDetails::getStaffType, 1);
        wrapper.lambda().eq(AccountDetails::getDetailType, 8);
        accountDetailsService.saveOrUpdate(accountDetails, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R deleteSalesProxy(Long id) throws Exception {
        SalesProxy salesProxy = baseMapper.selectById(id);
        if (salesProxy == null){
            throw new Exception("订单不存在");
        }
        if (salesProxy.getState().intValue() != 0){
            throw new Exception("订单不是在售状态，不能删除");
        }
        baseMapper.deleteById(id);
        deleteMethod(salesProxy);
        return R.status(true);
    }

    /**
     * 删除主方法
     * @param salesProxy
     * @return
     */
    private R deleteMethod(SalesProxy salesProxy) throws Exception {
        QueryWrapper<SalesProxyDetail> detailQueryWrapper = new QueryWrapper();
        detailQueryWrapper.eq("sales_id", salesProxy.getId());
        List<SalesProxyDetail> orderDetails = detailService.getBaseMapper().selectList(detailQueryWrapper);
        if (CollectionUtils.isNotEmpty(orderDetails)){
            List<Long> detailIds = orderDetails.stream().map(SalesProxyDetail::getId).collect(Collectors.toList());

            QueryWrapper<SalesProxyDetail> queryWrapper = new QueryWrapper();
            queryWrapper.eq("sales_id", salesProxy.getId());
            log.info("删除代销发货商品明细");
            detailService.getBaseMapper().delete(queryWrapper);

            QueryWrapper<SalesOrderDetailStock> stockQueryWrapper = new QueryWrapper<>();
            stockQueryWrapper.in("detail_id", detailIds);
            log.info("删除代销发货商品下的库存关系表数据");
            detailStockService.getBaseMapper().delete(stockQueryWrapper);

        }
        return R.status(true);
    }
}
